package keter.domain;

import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OrderBy;
import javax.persistence.Transient;
import javax.validation.constraints.Pattern;

import keter.domain.base.BaseEntity;
import keter.domain.validation.PasswordConstraint;
import keter.util.CollectionsUtil;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
// import org.hibernate.annotations.Table;
import org.hibernate.validator.constraints.NotEmpty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.common.collect.Lists;

/**
 * <p>
 * Class : keter.domain.Account
 * <p>
 * Descdription: 用户账户 框架只提供用于登录认证的账户基本功能 具体用户特性需要工程实现
 * 
 * @author gulixing@msn.com
 * @version 1.0.0
 */
@Entity
@PasswordConstraint
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Account extends BaseEntity {
    /**
     * Logger for this class
     */
    private static final Logger logger = LoggerFactory.getLogger(Account.class);
    
    @NotEmpty(message = "账户名不能为空")
    @Pattern(regexp="^[a-zA-Z-0-9_]+$",message = "账户名只允许使用字母、数字、中横线、下划线")
    private String name;
    
    @NotEmpty(message = "密码不能为空")
    private String password;

    @Transient
    private String repeatPassword;

    @NotEmpty
    private String status = Status.ENABLED.toString();

    public Account() {

    }

    @Column(unique = true)
    public String getName() {
        return name;
    }

    @JsonIgnore
    public String getPassword() {
        return password;
    }

    @JsonIgnore
    @Transient
    public String getRepeatPassword() {
        return repeatPassword;
    }

    private List<Role> roleList = Lists.newArrayList();

    @Transient
    public String getRoleLabels() {
        return CollectionsUtil.extractToString(roleList, "label", ", ");
    }

    // 多对多定义
    //解决[paper/user/findteacher/5]问题，疑似openSessionInViewFilter失效？
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "account_role", joinColumns = { @JoinColumn(name = "account_id") }, inverseJoinColumns = { @JoinColumn(name = "role_id") })
    // Fecth策略定义
    @Fetch(FetchMode.SUBSELECT)
    // 集合按id排序
    @OrderBy("id ASC")
    @JsonIgnore
    @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
    public List<Role> getRoleList() {
        return roleList;
    }
    
    @Transient
    @JsonIgnore
    public boolean hasRole(String roleName){
    	return getRoleNames().contains(roleName);
    }

    @Transient
    @JsonIgnore
    public String getRoleNames() {
        return CollectionsUtil.extractToString(roleList, "name", ", ");
    }
    
    
    public void removeRole(Role role) {
        roleList.remove(role);
    }

    @Transient
    public void setRole(Role role) {
        this.roleList = Lists.newArrayList();
        this.roleList.add(role);
    }
    
    public void setRoleList(List<Role> roleList) {
    	this.roleList = roleList;
    }

    public String getStatus() {
        return status;
    }

    public void setName(String account) {
        this.name = account;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public void setRepeatPassword(String repeatPassword) {
        this.repeatPassword = repeatPassword;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    // 多对一
    private Unit unit;
    @JsonIgnore
    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="unit_id")//关联主键
    public Unit getUnit() {
        return unit;
    }
    public void setUnit(Unit unit) {
        this.unit = unit;
    }
    @Transient
    public String getUnitName() {
        return unit!=null?unit.getName():"";
    }
	
	public static enum Status{
	    ENABLED,   //启用，默认状态
	    LOCKED,    //锁定
	    DISABLED,  //禁用
	    DELETED    //删除
	}
}